<template>
    <div class="process-detail-form">
        <a-row class="process-detail-form-row">
            <a-col :span="20" class="process-detail-form-col">
                <div class="process-detail-form-header">
                    <div v-if="title.firstName" class="process-detail-form-header-title">
                        <span>{{ title.firstName }}</span>
                        <span>{{ title.secondName }}</span>
                    </div>
                </div>
                <div class="process-detail-form-content">
                    <!-- 审批内容区 -->
                    <component
                        ref="formRef"
                        :is="`Form${state.formId}`"
                        :id="state.formData.id"
                        editType="edit"
                        :formData="state.formData"
                        :isProcess="true"
                    />
                    <FormModalAction
                        class="process-detail-form-content-operate"
                        :processStatus="processIdInfo.processStatus"
                        :isInitiatorUser="isInitiatorUser"
                        :isShowUrge="isShowUrge"
                        :isCurrentOperatorUser="isCurrentOperatorUser"
                        :isStartNode="isStartNode"
                        :basePermission="processDetail.basePermission"
                        :approve-button-config="state.approveButtonConfig"
                        @approve="handleApproveButtonClick"
                    />
                </div>
            </a-col>
            <a-col :span="4" class="process-detail-form-col approval-history-wrapper">
                <approval-history
                    v-if="!isNullOrEmpty(processDetail)"
                    :approve-task-list="processDetail.approveTaskList"
                />
            </a-col>
        </a-row>
        <a-modal
            :visible="state.approvalCommentsModalVisible"
            :width="432"
            :centered="true"
            :mask-closable="true"
            :title="t('workflow.leavingMessage')"
            @cancel="handleCancelApprove"
        >
            <template #footer>
                <a-button class="default-btn" @click="handleCancelApprove">
                    {{ t('cancel') }}
                </a-button>
                <a-button
                    type="primary"
                    :danger="currentApproveAction.isDanger || false"
                    :class="[state.approvalActionType === 'APPROVE' ? 'agree-btn' : 'danger-btn']"
                    :loading="state.confirmApprovalLoading"
                    @click="currentApproveAction.action"
                >
                    <template #icon>
                        <component :is="currentApproveAction.icon" />
                    </template>
                    {{ currentApproveAction.title }}
                </a-button>
            </template>
            <div class="process-info-warp">
                <div class="process-form-item">
                    <span class="approval-comments">{{ t('workflow.approveRemark') }}</span>
                    <a-textarea
                        v-model:value="state.approveRemark"
                        :placeholder="t('placeholderInput')"
                        :auto-size="{ minRows: 7, maxRows: 7 }"
                    />
                    <div v-if="state.approvalActionType === 'BACK'" class="option">
                        <span class="title"> {{ t('workflow.backNode') }}</span>
                        <div class="form-item">
                            <a-select style="width: 50%" label-in-value @change="handleBackNodeChange">
                                <a-select-option
                                    v-for="backNode in state.approveBackNodeList"
                                    :key="backNode.processNodeId"
                                    :value="backNode.processNodeId"
                                >
                                    {{ backNode.processNodeName }}
                                </a-select-option>
                            </a-select>
                        </div>
                    </div>
                </div>
            </div>
        </a-modal>
    </div>
</template>

<script lang="ts">
    import { defineComponent, ref, reactive, computed, onMounted, Ref, UnwrapNestedRefs, nextTick } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    import { useI18n } from 'vue-i18n'
    import { isEmptyArr, isNullOrEmpty } from '@/utils/is'
    import FormModalAction from './FormModalAction'
    import ApprovalHistory from './ApprovalHistory.vue'
    import { message } from 'ant-design-vue'
    import {
        fetchProcessDetail,
        getRollbackNodeList,
        processCancel,
        processInstanceRollback,
        setProcessApproval,
        setProcessUrge
    } from '@/apis/sys/process'
    import { $getPublishedApplicationId } from '@/utils/common'
    import { useUserStore } from '@/store/modules/user'

    // 批量注册表单组件
    const files = import.meta.globEager('../../../form/*.vue')
    // 当前应用下全部表单组件
    const fromComponents: Record<string, any> = {}
    // 遍历生成对象集合
    for (const key in files) {
        const component = files[key].default
        let name = key.substring(key.lastIndexOf('/') + 1, key.lastIndexOf('.vue'))
        component.name = name
        fromComponents[name] = component
    }

    // 表单提交数据对象
    interface ParamsData {
        pageId: string
        applicationId: number
        processInstanceName: string
        bodyConfig: Array<{ key: string; value: any }>
        // 处理子表单
        childrenList: Array<{ key: string; value: any }>
    }
    interface ApprovalStrategy {
        title: string
        icon: string
        isDanger?: boolean
        // 点击确认审批意见弹窗所执行的动作
        action: () => void
        // 处理不同类型审批动作的逻辑（部分不需要打开审批意见弹窗）
        handleApprove: () => void
    }
    interface ProcessDetailState {
        formId: number
        formData: Record<string, any>
        approveRemark: string
        backTargetNode: string
        confirmApprovalLoading: boolean
        approvalCommentsModalVisible: boolean
        approveBackNodeList: any[]
        approvalActionType: ApprovalActionType
        approveButtonConfig: ButtonSetting[]
    }
    export default defineComponent({
        name: 'ProcessDetail',
        components: {
            FormModalAction,
            ...fromComponents,
            ApprovalHistory
        },
        setup() {
            const route = useRoute()
            const router = useRouter()
            const { t } = useI18n()

            const userStore = useUserStore()
            const applicationId = $getPublishedApplicationId()
            const formRef = ref<{
                formRef: Ref
                formState: UnwrapNestedRefs<any>
                getParams: (formState: object) => ParamsData
                handleSubmit: (exc: (data: ParamsData) => void) => void
                onSubmit: () => void
                resetForm: () => void
                clearCache: () => void
                controlFormItemVisible: (key: string, visible: boolean) => void
                controlFormItemDisabled: (key: string, disabled: boolean) => void
            } | null>(null)
            const processDetail = ref<ProcessDetail>({
                pageData: {},
                pageFieldIdList: [],
                reportPermission: {},
                organizationList: [],
                basePermission: {},
                approveInfo: {
                    processInstanceId: '',
                    processInstanceName: '',
                    operatorId: 0,
                    operatorName: '',
                    taskId: '',
                    taskName: '',
                    status: '',
                    applyUserId: 0,
                    approveNodeKey: '',
                    urged: false,
                    processStartId: ''
                },
                approveTaskList: [],
                pageType: '',
                approveButtonConfig: { buttonSetting: [] }
            })

            const state = reactive<ProcessDetailState>({
                formId: 0,
                formData: {},
                confirmApprovalLoading: false,
                approvalCommentsModalVisible: false,
                approvalActionType: 'APPROVE',
                approveRemark: '',
                backTargetNode: '',
                approveBackNodeList: [],
                approveButtonConfig: []
            })
            const title = computed<{ firstName: string; secondName: string }>(() => {
                if (isNullOrEmpty(processDetail.value)) {
                    return { firstName: '', secondName: '' }
                }
                const { approveInfo } = processDetail.value
                return {
                    firstName: approveInfo.processInstanceName ? `${approveInfo.processInstanceName} / ` : '',
                    secondName: approveInfo.taskName
                }
            })
            // 是不是组织机构 表单
            const isOrganization = computed(() => {
                return processDetail.value && processDetail.value.pageType === 'ORGANIZATION'
            })

            // 是否是当前流程的发起人
            const isInitiatorUser = computed(() => {
                const userInfo = userStore.getUserInfo
                return userInfo?.id === processDetail.value.approveInfo?.applyUserId
            })
            // 是否显示催办 撤回按钮
            const isShowUrge = computed(() => {
                return (
                    isInitiatorUser.value &&
                    processIdInfo.processStatus === 'my_create' &&
                    processDetail.value.approveInfo?.status === 'IN_PROCESS'
                )
            })
            // 获取当前登录用户是否是当前审批节点用户
            const isCurrentOperatorUser = computed(() => {
                const userInfo = userStore.getUserInfo
                return userInfo?.id === processDetail.value.approveInfo?.operatorId
            })
            // 是否显示流程提交按钮
            const isStartNode = computed(() => {
                if (!processDetail.value.approveInfo.approveNodeKey) {
                    return false
                }
                return (
                    isCurrentOperatorUser.value &&
                    processDetail.value.approveInfo.approveNodeKey.indexOf('startNode') > -1
                )
            })
            // 获取流程信息
            const getProcessDetail = (processInfo: {
                processInstanceId: string
                taskId: string
                processStartId: string
            }) => {
                const { processInstanceId, taskId, processStartId } = processInfo
                const data = {
                    sort: {
                        last_modified_date: 'DESC'
                    },
                    pageSize: 1,
                    pageNo: 1,
                    filter: {
                        process_start_id: processStartId
                    }
                }
                fetchProcessDetail(processInstanceId, taskId, data).then((response: ProcessDetail) => {
                    if (isNullOrEmpty(response)) {
                        // 处理无数据错误
                        message.error(t('noProcessError'))
                        return
                    }
                    processDetail.value = response
                    const {
                        pageData: { dataList = [] }
                    } = response
                    // 需要审批的数据,经与徐欣确认该数组最多只有一条数据
                    state.formData = dataList[0]
                    state.formId = response.pageData.pageId
                    state.approveButtonConfig = response.approveButtonConfig.buttonSetting

                    nextTick(() => {
                        response.pageFieldIdList.forEach(field => {
                            formRef.value?.controlFormItemVisible(field.filedId, field.visibilityFlag)
                            formRef.value?.controlFormItemDisabled(field.filedId, !field.editableFlag)
                        })
                    })
                })
            }
            const { processInstanceId, taskId, processStatus } = route.params
            const { processStartId } = route.query
            const processIdInfo = { processInstanceId, taskId, processStatus }

            onMounted(() => {
                getProcessDetail({ ...processIdInfo, processStartId })
            })

            // 流程表单 审批处理 同意、拒绝、撤销
            const handleApproveRejectRevokeConfirm = () => {
                // 判断是否有审批意见
                if (!state.approveRemark) {
                    message.error(t('workflow.approveRemarkEmpty'))
                    return
                }
                // TODO: 是否还有系统流程的需求
                // if (this.isOrganization) {
                //   this.handleOrganizationForm();
                //   return;
                // }
                if (!formRef.value) {
                    return
                }

                formRef.value.handleSubmit(formData => {
                    const data: {
                        processInstanceId: string
                        taskId: string
                        applicationId: number
                        approveAction: string
                        approveRemark: string
                        dataId: number
                        bodyConfig: Array<{ key: string; value: any }>
                        childrenList: Array<{ key: string; value: any }>
                    } = { ...formData }
                    state.confirmApprovalLoading = true
                    data.approveAction = state.approvalActionType
                    data.approveRemark = state.approveRemark
                    data.applicationId = applicationId
                    data.dataId = state.formData.id
                    data.processInstanceId = processIdInfo.processInstanceId as string
                    data.taskId = processIdInfo.taskId as string
                    // ==老版本备注== 当前页面是我发起页面 走撤销接口（processCancel） 其他走流程批量审批接口（setProcessApproval）
                    // TODO：很奇怪的逻辑，应该根据操作类型来判断，待确认
                    const usedAPi = processIdInfo.processStatus === 'my_create' ? processCancel : setProcessApproval
                    usedAPi(data)
                        .then(() => {
                            // 成功清空前端缓存
                            formRef.value!.clearCache()
                            message.success(t('message.submitSuccess'))
                            // 发起成功后，页面跳转到我的流程 我处理的--》tab
                            router.replace(import.meta.env.VITE_PUBLIC_PATH + '/process?type=2')
                        })
                        .finally(() => {
                            state.confirmApprovalLoading = false
                        })
                })
            }
            // 处理流程退回，如果流程退回至申请人重新提交表单时也需要再次调用退回接口
            const handleApprovalBackSubmit = (isBack = true) => {
                const { approveNodeKey, processInstanceId, taskId, operatorId, operatorName } =
                    processDetail.value!.approveInfo
                const targetNodeId = !isStartNode.value ? state.backTargetNode : approveNodeKey
                if (isNullOrEmpty(targetNodeId)) {
                    message.error(t('workflow.checkError.noSelectBackNode'))
                    return
                }
                // 判断退回时是否有审批意见,流程退回之后在提交没有审批意见
                if (isBack && isNullOrEmpty(state.approveRemark)) {
                    message.error(t('workflow.approveRemarkEmpty'))
                    return
                }
                const parameter = {
                    processInstanceId,
                    taskId,
                    targetNodeId,
                    rollbackRemark: state.approveRemark,
                    operatorId,
                    operatorName,
                    bodyConfig: formRef.value!.getParams(formRef.value!.formState).bodyConfig,
                    dataId: state.formData.id
                }

                state.confirmApprovalLoading = true
                processInstanceRollback(parameter)
                    .then(() => {
                        // 清空前端缓存
                        formRef.value!.clearCache()
                        message.success(t('message.submitSuccess'))
                        // 发起成功后，页面跳转到我的流程 -> 我处理的 tab
                        router.replace(import.meta.env.VITE_PUBLIC_PATH + '/process?type=2')
                    })
                    .finally(() => {
                        state.confirmApprovalLoading = false
                    })
            }
            // 审批策略对象
            const approvalStrategyMap: Record<ApprovalActionType, ApprovalStrategy> = {
                // 同意
                APPROVE: {
                    icon: 'check-circle-outlined',
                    title: t('confirm'),
                    action: handleApproveRejectRevokeConfirm,
                    handleApprove: () => {
                        state.approvalCommentsModalVisible = true
                        state.approveRemark = t('workflow.actions.agree')
                    }
                },
                // 拒绝
                REJECT: {
                    isDanger: true,
                    icon: 'close-circle-outlined',
                    title: t('workflow.actions.refuse'),
                    action: handleApproveRejectRevokeConfirm,
                    handleApprove: () => {
                        state.approvalCommentsModalVisible = true
                        state.approveRemark = t('workflow.actions.refuse')
                    }
                },
                // 回退
                BACK: {
                    isDanger: true,
                    icon: 'rollback-outlined',
                    title: t('workflow.actions.back'),
                    action: handleApprovalBackSubmit,
                    handleApprove: () => {
                        // 回退,默认留言
                        state.approveRemark = t('workflow.actions.back')
                        state.confirmApprovalLoading = true
                        state.approvalActionType = 'BACK'
                        const { approveNodeKey, processInstanceId } = processDetail.value!.approveInfo
                        getRollbackNodeList({ approveNodeKey, processInstanceId, applicationId })
                            .then(res => {
                                // 成功清空前端缓存
                                formRef.value!.clearCache()
                                if (isEmptyArr(res.data)) {
                                    message.error(t('workflow.checkError.noBackNode'))
                                    return
                                }
                                state.approveBackNodeList = res.data
                                state.approvalCommentsModalVisible = true
                            })
                            .finally(() => {
                                state.confirmApprovalLoading = false
                            })
                    }
                },
                SUBMIT: {
                    icon: '',
                    title: '',
                    action: () => {},
                    handleApprove: () => {
                        handleApprovalBackSubmit(false)
                    }
                },
                // 催办
                URGE: {
                    icon: '',
                    title: '',
                    action: () => {},
                    handleApprove: () => {
                        state.confirmApprovalLoading = true
                        setProcessUrge(processDetail.value.approveInfo)
                            .then(() => {
                                // 成功清空前端缓存
                                formRef.value!.clearCache()
                                message.success(t('message.submitSuccess'))
                            })
                            .finally(() => {
                                state.confirmApprovalLoading = false
                            })
                    }
                },
                // 撤销
                REVOKE: {
                    icon: 'close-circle-outlined',
                    title: t('workflow.actions.undo'),
                    action: handleApproveRejectRevokeConfirm,
                    handleApprove: () => {
                        state.approvalCommentsModalVisible = true
                        state.approveRemark = t('workflow.actions.undo')
                    }
                }
            }
            // 当前审批动作类型
            const currentApproveAction = computed<ApprovalStrategy>(() => {
                return approvalStrategyMap[state.approvalActionType]
            })
            // 处理各种审批按钮点击
            const handleApproveButtonClick = (approvalAction: ApprovalActionType) => {
                state.approvalActionType = approvalAction
                approvalStrategyMap[approvalAction].handleApprove()
            }
            // 关闭审批意见弹窗
            const handleCancelApprove = () => {
                state.approvalCommentsModalVisible = false
            }
            /**
             * 回退节点选择发生变化
             */
            const handleBackNodeChange = option => {
                state.backTargetNode = option.key
            }
            return {
                t,
                formRef,
                isNullOrEmpty,
                title,
                state,
                processIdInfo,
                isInitiatorUser,
                isShowUrge,
                isCurrentOperatorUser,
                isStartNode,
                isOrganization,
                processDetail,
                currentApproveAction,
                handleApproveButtonClick,
                handleCancelApprove,
                handleBackNodeChange
            }
        }
    })
</script>

<style lang="less" scoped>
    .process-detail-form {
        height: 100%;
        background: #f1f3f4;

        &-row {
            height: 100%;
        }

        &-col {
            height: 100%;
            display: flex;
            flex-direction: column;
        }

        .approval-history-wrapper {
            background-color: #fafbfc;
        }

        &-header {
            position: relative;
            background: #fff;
            display: flex;
            height: 45px;
            justify-content: center;
            align-items: center;
            border-bottom: 1px solid #e1e4ed;

            &-title {
                //抹平不同长度标题造成的tabs位置变化的问题
                position: absolute;
                left: 0;
                padding-left: 1em;
                height: 45px;
                line-height: 45px;
                font-weight: bold;
                color: #8e97a8;
                font-size: 14px;

                & > span:nth-child(2) {
                    color: #0d0000;
                }
            }

            &-header-tab {
                flex: 1;
                display: flex;
                justify-content: center;
                height: 45px;
                align-items: flex-end;

                .tab {
                    margin-right: 60px;
                    padding: 0 10px 10px;
                    border-bottom: 2px solid #fff;
                    cursor: pointer;

                    &.active {
                        border-bottom: 2px solid #3875ff;
                    }
                }
            }
        }

        &-content {
            background: #fff;
            flex: 1;
            padding-bottom: 60px;
            overflow: auto;
            position: relative;
            width: 100%;
            margin: 0;
            padding: 20px;

            &-operate {
                text-align: center;
            }
        }

        &-content-wide {
            width: 100%;
            height: 100%;
            background: #fff;
            padding-bottom: 60px;
            overflow: auto;
        }
    }

    :deep(.@{ant-prefix}-timeline-item-head-custom) {
        background: rgba(0, 0, 0, 0);
    }
</style>

<i18n>
zh-CN:
  noProcessError: 没有获取到该流程信息
en-US:
  noProcessError: The process information was not obtained
</i18n>
